<template>
  <!-- 用于渲染 Three.js 场景的容器 -->
  <div ref="container" class="three-container"></div>
</template>
 
<script>
import * as THREE from 'three';
// 导入 FBX 模型加载器
import { FBXLoader } from 'three/addons/loaders/FBXLoader.js';
export default {
  name: 'ThreeModelLoader',
  data() {
    return {
      // 这里只保留需要响应式的数据，比如加载状态等
    };
  },
  mounted() {
    this.initThree(); // 初始化 Three.js 场景
    this.loadFBXModel(); // 加载 FBX 模型
    this.animate(); // 启动动画循环
  },
  methods: {
    initThree() {
      // 创建场景
      this.scene = new THREE.Scene();
      // this.scene.background = new THREE.Color(0xa0c6ff); // 天空蓝色背景
      const textureLoader = new THREE.TextureLoader();
      textureLoader.load('/fbx/floor3.png', (texture) => {
        this.scene.background = texture;
      });
      // 创建透视相机
      const container = this.$refs.container;
      const width = container.clientWidth;
      const height = container.clientHeight;
      
      this.camera = new THREE.PerspectiveCamera(75, width / height, 0.1, 3000);
      // 设置相机位置
      this.camera.position.set(0, 1300, 1500); // x, y, z 坐标都可以自定义
      // 设置相机注视点
      const target = new THREE.Vector3(0, 1000, 0);
      this.camera.lookAt(target);

      // 创建渲染器
      this.renderer = new THREE.WebGLRenderer();
      this.renderer.setSize(width, height);
      this.$refs.container.appendChild(this.renderer.domElement);

      // 创建轨道控制器
      const OrbitControls = require('three/addons/controls/OrbitControls.js').OrbitControls;
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);
      this.controls.minDistance = 800;   // 最小距离，根据实际场景调整
      this.controls.maxDistance = 2500;  // 最大距离，根据实际场景调整
      // 同步设置 controls.target
      this.controls.target.copy(target);
      this.controls.update();
      // 添加环境光1
      const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
      this.scene.add(ambientLight);

      // 添加平行光
      const directionalLight = new THREE.DirectionalLight(0xffffff, 2.5);
      directionalLight.position.set(1, 1, 1);
      this.scene.add(directionalLight);

      window.addEventListener('resize', this.onWindowResize);
    },
    loadFBXModel() {
      const loader = new FBXLoader();
      loader.load(
      // '/fbx/ABB-4600.fbx',
      '/fbx/human-zb.fbx',
      //'/fbx/Human.fbx',
      (object) => {
      // 存储所有材质名称
      // const materialNames = new Set();
      
      // object.traverse((child) => {
      //   if (child.isMesh && child.material) {
      //     const materials = Array.isArray(child.material) ? child.material : [child.material];
      //     materials.forEach((mat) => {
      //       if (mat.name) {
      //         materialNames.add(mat.name);
      //       }
      //     });
      //   }
      // });
      
      // console.log('模型需要的材质/贴图名称:', Array.from(materialNames));
      // 手动为模型添加贴图
      const textureLoader = new THREE.TextureLoader();
      // 贴图文件名与材质名的映射（根据你的实际贴图和材质名填写）
      const textureMap = {
        'middleage_lightskinned_male_diffuse2': '/fbx/middleage_lightskinned_male_diffuse2.png',
        'short02_diffuse': '/fbx/short02_diffuse.png',
        'brown_eye': '/fbx/brown_eye.png',
        'male_casualsuit01_diffuse': '/fbx/male_casualsuit01_diffuse.png',
        // 继续添加其它贴图
      };

      object.traverse((child) => {
        if (child.isMesh && child.material) {
          // 处理多材质情况
          const materials = Array.isArray(child.material) ? child.material : [child.material];
          materials.forEach((mat) => {
            // 根据材质名自动匹配贴图
            for (const key in textureMap) {
              // 强制不透明
              mat.transparent = false;
              mat.opacity = 0.8;
              if (mat.name && mat.name.includes(key)) {
                mat.map = textureLoader.load(textureMap[key]);
                mat.needsUpdate = true;
              }
              // 如果有法线贴图
              if (mat.name && mat.name.includes('normal') && textureMap['male_casualsuit01_normal']) {
                mat.normalMap = textureLoader.load(textureMap['male_casualsuit01_normal']);
                mat.needsUpdate = true;
              }
            }
          });
        }
      });
          // 存储骨骼引用
          this.bones = {};
          this.fbxModel = object;
          this.fbxModel.position.set(-2, 1, 0);
          this.scene.add(this.fbxModel);
          console.log('FBX 模型加载成功');
          // 遍历查找骨骼
          // object.traverse((child) => {
          //   if (child.isBone) {
          //     this.bones[child.name] = child;
          //     if (this.bones['upperarm01R']) {
          //     this.bones['upperarm01R'].rotation.set(Math.PI / 4, 0, 0);
          //     }
          //     //  if (this.bones['lowerarm01R']) {
          //     // //  console.log('找到右小臂骨骼');
          //     // this.bones['lowerarm01R'].rotation.set(0, Math.PI / 2, 0);
          //     // }
          //   }
          // });                
        },
        undefined,
        (error) => {
          console.error('FBX 模型加载失败:', error);
        }
      );
    },

    setBoneRotation(boneName, Roll, Pitch, Yaw) {   
      console.log('收到旋转请求:', boneName, Roll, Pitch, Yaw);
      // 角度转弧度
      const radRoll = THREE.MathUtils.degToRad(Roll);
      const radPitch = THREE.MathUtils.degToRad(Pitch);
      const radYaw = THREE.MathUtils.degToRad(Yaw);
      // 每次都重新遍历查找骨骼
      if (this.fbxModel) {
        this.bones = {};
        this.fbxModel.traverse((child) => {
          if (child.isBone) {
            this.bones[child.name] = child;
            if (this.bones[boneName]) {
            this.bones[boneName].rotation.set(radYaw, radRoll, radPitch);
            }
          }
        });
      }     
    },
    animate() {
      requestAnimationFrame(this.animate);
      if (this.controls) this.controls.update();
      if (this.renderer && this.scene && this.camera) {
        this.renderer.render(this.scene, this.camera);
      }
    },
    onWindowResize() {
  const container = this.$refs.container;
  if (this.camera && this.renderer && container) {
    const width = container.clientWidth;
    const height = container.clientHeight;
    this.camera.aspect = width / height;
    this.camera.updateProjectionMatrix();
    this.renderer.setSize(width, height);
  }
    },
  },
  beforeUnmount() {
    // 移除窗口大小变化的监听器
    window.removeEventListener('resize', this.onWindowResize);
    if (this.controls) this.controls.dispose();
    if (this.renderer) this.renderer.dispose();
    if (this.scene && this.fbxModel) this.scene.remove(this.fbxModel);
    if (this.scene && this.glbModel) this.scene.remove(this.glbModel);
  },
};
</script>
 
<style scoped>
.three-container {
  width: 100%;
  height: 100%;
}
</style>